from .meta import *
from meta_service.utils import mkdir_if_not_exist
import os

class IndexHandle:

    def __init__(self,index_meta:IndexMeta) -> None:
        self.cur_meta = index_meta
        self.__rebuild_with_index_meta()
        # temp index
        self.is_temp_index = False
        self.real_meta = index_meta
        self.temp_meta = None
    
    def __str__(self) -> str:
        showlis = [
            f"IndexHandle: {self.real_meta.index_name}",
            f" tis: {self.real_meta.tis_path}",
            f" index: {self.real_meta.index_name}",
            f" cur-point-to-path: {self.index_path}"
        ]
        return "\n".join(showlis)
    
    def IsTempIndex(self) -> bool:
        return self.is_temp_index
    
    def GetTopicName(self) -> str:
        return str(self.real_meta.topic_name)
    
    def GetIndexName(self) -> str:
        return str(self.real_meta.index_name)

    def GetIndexPath(self) -> str:
        """
        临时index状态时: 返回临时文件的地址
        正式index状态时: 返回正式文件的地址
        """
        return self.index_path
    
    def set_temp_index(self,temp_meta:IndexMeta):
        self.is_temp_index = True
        self.temp_meta = temp_meta
        self.cur_meta = temp_meta
        self.__rebuild_with_index_meta()
    
    def __rebuild_with_index_meta(self):
        self.tis_path = self.cur_meta.tis_path
        self.topic_name = self.cur_meta.topic_name
        self.index_name = self.cur_meta.index_name
        self.topic_path = os.path.join(self.tis_path,self.topic_name)
        self.index_path = os.path.join(self.topic_path,self.index_name)
    
    def isVaild(self):
        if self.is_temp_index:
            return True
        return os.path.exists(self.index_path)
    
    def TurnOn(self):
        """
        文件转正
        """
        if self.is_temp_index:
            if MoveIndex(self.temp_meta,self.real_meta):
                self.cur_meta = self.real_meta
                self.is_temp_index = False
                self.__rebuild_with_index_meta()
                return True
        else:
            print("it is not a temp file, you can use it directly")
        return False


class TopicHandle:

    def __init__(self,tis_path:str,topic_name) -> None:
        self.tis_path = tis_path
        self.topic_name = topic_name
        self.topic_path = os.path.join(tis_path,topic_name)
        mkdir_if_not_exist(self.topic_path)
        self.file_list = None
        self.index_list = None
    
    def __str__(self) -> str:
        self.__get_index_filename_list()
        all = "No Index Here"
        if len(self.file_list) > 0:
            all = ",".join([ str(name) for name in self.file_list ])
        return f"TopicHandle: {self.topic_name}, \n tis:{self.tis_path} \n path:{self.topic_path} \n Index: { all }"
    
    def __get_index_filename_list(self):
        files = os.listdir(self.topic_path)
        file_set = set()
        for filename in files:
            file_path = os.path.join(self.topic_path,filename)
            if os.path.isfile(file_path):
                file_set.add(filename)
        self.file_list = list(file_set)
        self.file_list.sort()
    
    def __build_index_handle_list(self) -> list[IndexHandle]:
        self.__get_index_filename_list()
        index_handle_list = []
        for filename in self.file_list:
            index_handle = IndexHandle(
                IndexMeta(
                    self.tis_path,
                    self.topic_name,
                    filename
                )
            )
            index_handle_list.append(index_handle)
        return index_handle_list
    
    def HasIndex(self,index_name:str) -> bool:
        self.__get_index_filename_list()
        return index_name in self.file_list
    
    def GetIndexHandle(self,index_name:str):
        index_list = self.GetIndexList()
        if index_name in index_list:
            return IndexHandle(
                IndexMeta(
                    self.tis_path,
                    self.topic_name,
                    index_name
                )
            )
        return None

    def GetIndexList(self):
        self.__get_index_filename_list()
        return self.file_list
    
    def GetIndexHandleList(self):
        # 由于index可能存在增删, 每次获取都要重建
        return self.__build_index_handle_list()
    
    def NewTempIndex(self,index_name:str):
        if self.HasIndex(index_name):
            raise Exception(f"index: {index_name} already exist")
        temp_file_path = os.path.join(self.tis_path,CACHE_TOPIC_NAME)
        tempfile = TempFile(temp_file_path)
        temp_meta = IndexMeta(
            self.tis_path,
            CACHE_TOPIC_NAME,
            tempfile.FileName()
        )
        real_meta = IndexMeta(
            self.tis_path,
            self.topic_name,
            index_name
        )
        # create a handle for index
        index_handle = IndexHandle(real_meta)
        # turn it to temp index
        index_handle.set_temp_index(temp_meta)
        return index_handle

